package cn.com.dhcc.ddi.datasource.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.dhcc.app.core.base.BaseController;
import cn.com.dhcc.app.core.exception.DaoException;
import cn.com.dhcc.app.core.exception.NiceException;
import cn.com.dhcc.app.core.exception.ServiceException;
import cn.com.dhcc.app.core.handler.dbhandler.SingleTransationCircleWithOutResult;
import cn.com.dhcc.app.core.handler.modulehandler.WhereCondition;
import cn.com.dhcc.app.core.handler.pagerhandler.Pager;
import cn.com.dhcc.app.core.handler.pagerhandler.PagerData;
import cn.com.dhcc.app.core.pubmodule.sysmgr.usermgr.service.CmUserMgrService;
import cn.com.dhcc.app.core.pubmodule.sysmgr.usermgr.vo.UserInfoVo;
import cn.com.dhcc.app.core.service.BaseService;
import cn.com.dhcc.app.core.util.StrUtil;
import cn.com.dhcc.app.pub.CM;
import cn.com.dhcc.ddi.datamapping.dao.DataMappingDao;
import cn.com.dhcc.ddi.datamapping.vo.DataMapping;
import cn.com.dhcc.ddi.datasource.dao.DataSourceDao;
import cn.com.dhcc.ddi.datasource.dao.TableColDao;
import cn.com.dhcc.ddi.datasource.dao.TableInfoDao;
import cn.com.dhcc.ddi.datasource.vo.DataSourceVo;
import cn.com.dhcc.ddi.datasource.vo.TableColVo;
import cn.com.dhcc.ddi.datasource.vo.TableInfoVo;
/**
 * 
 * 数据源服务类
 * @Author: fxx
 * @date: 2017-5-16
 *
 */
@Service
public class DataSourceService extends BaseService {
	@Autowired
    DataSourceDao dataSourceDao;
	@Autowired
	TableInfoDao tableInfoDao;
	@Autowired
	TableColDao tableColDao;
	@Autowired
	DataMappingDao dataMappingDao;
	@Autowired
	CmUserMgrService userMgrService;
	@Autowired
	TableInfoService tableInfoService;
	@Autowired
	TableColService tableColService;
	
	/**
	 * 
	 * @Title: getPagerList
	 * @Description: 获取数据源列表
	 * @param @param pager
	 * @param @param searchParameter
	 * @param @param id
	 * @param @return
	 * @param @throws ServiceException 参数
	 * @return PagerData<DataSourceVo> 返回类型
	 * @throws
	 */
	public PagerData<DataSourceVo> getPagerList(Pager pager, WhereCondition searchParameter) throws ServiceException {
		try {
			return dataSourceDao.getPagerList(pager, searchParameter);
		} catch (DaoException e) {
			throw new ServiceException("获取数据源列表失败", e);
		}
	}
	
	/**
	 * 获取全部数据源列表
	 * @return 全部数据源列表
	 * @throws ServiceException
	 */
	public List<DataSourceVo> getDsList() throws ServiceException {
		try {
			return dataSourceDao.getDsList();
		} catch (DaoException e) {
			throw new ServiceException("获取全部数据源列表失败", e);
		}
	}
	
	/**
	 * 获取当前用户全部数据源列表
	 * @return 全部数据源列表
	 * @throws ServiceException
	 */
	public List<DataSourceVo> getDsList(WhereCondition searchParameter) throws ServiceException {
		try {
			return dataSourceDao.getDsList(searchParameter);
		} catch (DaoException e) {
			throw new ServiceException("获取全部数据源列表失败", e);
		}
	}
	
	/**
	 * 根据id获取数据源
	 * @param  id 数据源id
	 * @urn 数据源信息
	 * @throws ServiceException
	 */
	public DataSourceVo getDataSourceById(String id) throws ServiceException {
		try {
			return dataSourceDao.getById(id);
		} catch (DaoException e) {
			throw new ServiceException("根据id获取数据源失败", e);
		}
	}

	/**
	 * 
	 * @Title: update
	 * @Description: 更新数据源
	 * @param @param obj
	 * @param @return
	 * @param @throws ServiceException 参数
	 * @return int 返回类型
	 * @throws
	 */
	public int update(DataSourceVo obj) throws ServiceException {
		try {
			return dataSourceDao.update(obj);
		} catch (DaoException e) {
			throw new ServiceException("更新数据源失败", e);
		}
	}
	
	/**
	 * 
	 * @Title: deleteDataSource
	 * @Description: 根据id删除数据源失败
	 * @param @param id
	 * @param @return
	 * @param @throws ServiceException 参数
	 * @return int 返回类型
	 * @throws
	 */
	public void deleteDataSource(final String id) throws ServiceException {

		try {
			CM.getDao().doInSingleTransationCircle("删除数据源信息", new SingleTransationCircleWithOutResult() {
				@Override
				public void actionInCircle() throws RuntimeException {
					try {
						List<String> tableIds = tableInfoService.getTableIdByDsId(id);
						dataSourceDao.delete(id);
						tableInfoService.deleteTbInfoByDsId(id);
						for (int i = 0; i < tableIds.size(); i++) {
							tableColService.deleteTbColInfoByTbId(tableIds.get(i));
						}
					} catch (Exception e) {
						throw new RuntimeException("数据源信息删除失败", e);
					}
				}
			});
		} catch (DaoException e) {
			throw new ServiceException("根据id删除数据源失败", e);
		}
	}
	
	/**
	 * 通过数据源获取表结构map ,key为表名
	 * @param dsId
	 * @return
     */
	public Map<String,TableInfoVo> getTableMap(String dsId) throws ServiceException {
		Map<String,TableInfoVo> tableMap = new HashMap<String,TableInfoVo>();
		try {
			List<TableInfoVo> tables =  tableInfoDao.getTableInfoByDsId(dsId);
			for (TableInfoVo table:	tables) {
				List<TableColVo> cols = tableColDao.getColsByTableId(table.getId());
				table.setTableColVos(cols);
				tableMap.put(table.getTableName().toLowerCase(),table);
			}
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
		return tableMap;
	}

	/**
	 * 
	 * @param dsId
	 * @param where
	 * @return
	 * @throws NiceException
	 */
	public boolean tabeleSqlTest(String dsMappingId, String tableId,String testSql)  throws  ServiceException,NiceException{
		try {
			boolean flag = false;
			DataMapping dsMappingVo = dataMappingDao.get(dsMappingId);
			String dsId = dsMappingVo.getSrcDsId();
			DataSourceVo vo = getDataSourceById(dsId);
			tableInfoDao.initDao(vo);
			
			TableInfoVo tableInfoVo = tableInfoDao.getById(tableId);
			testSql = "select count(*) from "+tableInfoVo.getSchema().toUpperCase()+"." + tableInfoVo.getTableName()+ " " + testSql;
			long num = tableInfoDao.userTableDao(testSql);
			if(num>=0){
				flag = true;
			}
			return flag;
		} catch (DaoException e) {
			throw new ServiceException("验证发布条件失败", e);
		}
	}
	
	/**
	 * 验证名称唯一性
	 * @param name
	 * @param checkStr
	 * @return
	 * @throws ServiceException
	 */
	public boolean isPropertyUnique(String propertyName, String newValue, String oldValue,HttpSession httpSession) throws ServiceException {
		try {
			if (newValue.equals(oldValue)) {
				return true;
			}
			WhereCondition searchParameter = new WhereCondition();
			searchParameter.where().eq(propertyName, newValue);
		
			Boolean isAdmin = BaseController.getCurrentUserInfo(httpSession).isSuperAdmin();
			String userId = BaseController.getCurrentUserInfo(httpSession).getId();
			UserInfoVo currentUser = userMgrService.getUserById(userId);
			if(!isAdmin){
				if(currentUser != null){
					String nodeIdsStr = currentUser.getExt2();
					if(StrUtil.isNotBank(nodeIdsStr)){
						String[] nodeIds = nodeIdsStr.split(",");
						searchParameter.andIn("node_id", nodeIds);
					}else{
						searchParameter.andEq("1", "2");
					}
				}
			}
			return dataSourceDao.count(searchParameter) == 0;
		} catch (DaoException e) {
			throw new ServiceException(e);
		}
	}
}
